/***************************************************
> Copyright (C) 2024 ==KINGYI== All rights reserved.
> File Name: serverfun.c
> Author:luohong
> Mail: 750232205@qq.com
> Created Time: 2024年09月21日 星期六 17时08分22秒
***************************************************/

#include <stdio.h>
#include "serverfun.h"
#include <string.h>

extern int sockfd;

MYSQL *mp = NULL;

struct userlist *uhead;
struct managerlist *mhead;
//设备端地址链表
struct addrlist *ahead;


//连接并初始化数据库
void initDB(){
    MYSQL *res = NULL;
    mp = mysql_init(NULL);
    res = mysql_real_connect(mp,"localhost","root","123","project",0,NULL,0);
    if(res == NULL){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }
    initUserInfoList();
    initManagerInfoList();

    //初始化设备端地址链表
    ahead = malloc(sizeof(struct addrlist));
    memset(ahead,0,sizeof(struct addrlist)); 
}

//加载用户信息到链表
void initUserInfoList(){
    uhead = malloc(sizeof(struct userlist));
    memset(uhead,0,sizeof(struct userlist));
    struct userlist *node = NULL;
    struct userlist *temp = uhead;

    struct userInfo user;
    memset(&user,0,sizeof(user));

    char sql[100] = {"select * from userinfo"};

    int ret = mysql_query(mp,sql);
    if(ret != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }
    
    MYSQL_RES *res1 = NULL;
    MYSQL_ROW row;

    res1 = mysql_store_result(mp);
    row = mysql_fetch_row(res1);

    while(row != NULL){
        user.id = atoi(row[0]);
        strcpy(user.name,row[1]);
        strcpy(user.passwd,row[2]);
        user.waterid = atoi(row[3]);
        user.elecid = atoi(row[4]);
        user.waterbalance = atoi(row[5]);
        user.elecbalance = atoi(row[6]);
        strcpy(user.phoneNumber,row[7]);
        node = malloc(sizeof(struct userlist));
        memset(node,0,sizeof(struct userlist));
        node->data = user;
        temp->next = node;
        node->next = NULL;
        temp = temp->next;
        row = mysql_fetch_row(res1);
    }
    mysql_free_result(res1);
}
//加载管理员信息到链表
void initManagerInfoList(){
    mhead = malloc(sizeof(struct managerlist));
    memset(mhead,0,sizeof(struct managerlist));
    struct managerlist *node = NULL;
    struct managerlist *temp = mhead;

    struct managerInfo manager;
    memset(&manager,0,sizeof(manager));

    char sql[100] = {"select * from managerlogin"};

    int ret = mysql_query(mp,sql);
    if(ret != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }
    
    MYSQL_RES *res1 = NULL;
    MYSQL_ROW row;

    res1 = mysql_store_result(mp);
    row = mysql_fetch_row(res1);

    while(row != NULL){
        manager.id = atoi(row[0]);
        strcpy(manager.name,row[1]);
        strcpy(manager.passwd,row[2]);
        strcpy(manager.phoneNumber,row[3]);
        node = malloc(sizeof(struct managerlist));
        memset(node,0,sizeof(struct managerlist));
        node->data = manager;
        temp->next = node;
        node->next = NULL;
        temp = temp->next;
        row = mysql_fetch_row(res1);
    }
    mysql_free_result(res1);
}
//登录
int login(struct msg msge){
    int flag = 0;
    initManagerInfoList();
    char res[50] = {0};
    int ret = 0;
    struct userlist *utemp = uhead->next;
    struct managerlist *mtemp = mhead->next;
    struct login_register data;
    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
	node = cJSON_GetObjectItem(json,"identity");
	if(node == NULL){
		printf("can't find identity\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.identity = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"id");
	if(node == NULL){
		printf("can't find id\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.id = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"pwd");
	if(node == NULL){
		printf("can't find pwd\n");
		exit(-1);
	}
    if(node->type == cJSON_String){
		strcpy(data.pwd,node->valuestring);
    }
    if(data.identity == 1){
        //用户登录
        memset(res,0,sizeof(res));
        while(utemp != NULL){
            if(utemp->data.id == data.id && (strcmp(utemp->data.passwd,data.pwd) == 0)){
                strcpy(res,"success");
                flag = 1;
                break;
            } 
            utemp = utemp->next;    
        }
        if(utemp == NULL){
            strcpy(res,"Failed, incorrect ID or password");
        }
        ret = sendto(sockfd,res,strlen(res),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
        if(ret == -1){
            perror("sendto");
            exit(-1);
        }
    }else if(data.identity == 2){
        //管理员登录
        memset(res,0,sizeof(res));
        while(mtemp != NULL){
            if(mtemp->data.id == data.id && (strcmp(mtemp->data.passwd,data.pwd) == 0)){
                strcpy(res,"success");
                flag = 1;
                break;
            } 
            mtemp = mtemp->next;    
        }
        if(mtemp == NULL){
            strcpy(res,"Failed, incorrect ID or password");
        }
        ret = sendto(sockfd,res,strlen(res),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
        if(ret == -1){
            perror("sendto");
            exit(-1);
        } 
    }
}
//注册
void uormregister(struct msg msge){
    char res1[100] = {0};
    int ret = 0;
    struct userlist *utemp = uhead->next;
    struct managerlist *mtemp = mhead->next;
    struct login_register data;

    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
	node = cJSON_GetObjectItem(json,"identity");
	if(node == NULL){
		printf("can't find identity\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.identity = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"id");
	if(node == NULL){
		printf("can't find id\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.id = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"pwd");
	if(node == NULL){
		printf("can't find pwd\n");
		exit(-1);
	}
    if(node->type == cJSON_String){
		strcpy(data.pwd,node->valuestring);
    }
    node = cJSON_GetObjectItem(json,"name");
	if(node == NULL){
		printf("can't find name\n");
		exit(-1);
	}
    if(node->type == cJSON_String){
		strcpy(data.name,node->valuestring);
    }
    node = cJSON_GetObjectItem(json,"phoneNumber");
	if(node == NULL){
		printf("can't find phoneNumber\n");
		exit(-1);
	}
    if(node->type == cJSON_String){
		strcpy(data.phoneNumber,node->valuestring);
    }

    char sql[200] = {0};
    
    if(data.identity == 1){
        //用户注册
        memset(res1,0,sizeof(res1));
        while(utemp != NULL){
            if(utemp->data.id == data.id){
                strcpy(res1,"Failed, account already exists");
                break;
            }
            utemp = utemp->next;     
        }
        strcpy(res1,"success");
        memset(sql,0,sizeof(sql));
        sprintf(sql,"insert into userinfo(id,pwd,name,phoneNumber,waterbalance,elecbalance,waterid,elecid) values(%d,'%s','%s','%s',300,300,0,0)",data.id,data.pwd,data.name,data.phoneNumber);
        int ret1 = mysql_query(mp,sql);
        if(ret1 != 0){
            printf("%s\n",mysql_error(mp));
            mysql_close(mp);
            exit(-1);
        }
        //freeuserlist(uhead);
        initUserInfoList();
        ret = sendto(sockfd,res1,strlen(res1),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
        if(ret == -1){
            perror("sendto");
            exit(-1);
        }
    }else if(data.identity == 2){
        //管理员注册
        memset(res1,0,sizeof(res1));
        while(mtemp != NULL){
            if(mtemp->data.id == data.id){
                strcpy(res1,"Failed, account already exists");
                break;
            }
            mtemp = mtemp->next;     
        }
        strcpy(res1,"success");
        memset(sql,0,sizeof(sql));
        sprintf(sql,"insert into managerlogin (id,pwd,name,phoneNumber) values(%d,'%s','%s','%s')",data.id,data.pwd,data.name,data.phoneNumber);
        int ret1 = mysql_query(mp,sql);
        if(ret1 != 0){
            printf("%s\n",mysql_error(mp));
            mysql_close(mp);
            exit(-1);
        }
        freemanlist(mhead);
        initManagerInfoList();
        ret = sendto(sockfd,res1,strlen(res1),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
        if(ret == -1){
            perror("sendto");
            exit(-1);
        }
    } 
}
//绑定设备
void bindEqu(struct task msge){
    int ret = 0;
    struct bindEquit data;
    char sql[150]  = {0};
    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"equtype");
	if(node == NULL){
		printf("can't find equtype\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.equtype = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"uid");
	if(node == NULL){
		printf("can't find uid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.uid = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"eid");
	if(node == NULL){
		printf("can't find eid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.eid = node->valueint;
    }

    if(data.equtype == 1){
        //水表
        memset(sql,0,sizeof(sql));
        sprintf(sql,"update userinfo set waterid = %d where id = %d",data.eid,data.uid);
    }else if(data.equtype == 2){
        //电表
        memset(sql,0,sizeof(sql));
        sprintf(sql,"update userinfo set elecid = %d where id = %d",data.eid,data.uid);
    }
    printf("node1\n");
    int ret1 = mysql_query(mp,sql);
    if(ret1 != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }

    char res1[50] = "bind success";
    ret = sendto(sockfd,res1,strlen(res1),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
    if(ret == -1){
        perror("sendto");
        exit(-1);
    }

    freeuserlist(uhead);
    initUserInfoList();
}
//解绑设备
void unbingEqu(struct task msge){
    int ret = 0;
    struct bindEquit data;
    char sql[150]  = {0};
    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"equtype");
	if(node == NULL){
		printf("can't find equtype\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.equtype = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"uid");
	if(node == NULL){
		printf("can't find uid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.uid = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"eid");
	if(node == NULL){
		printf("can't find eid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.eid = node->valueint;
    }

    if(data.equtype == 1){
        //水表
        memset(sql,0,sizeof(sql));
        sprintf(sql,"update userinfo set waterid = 0 where id = %d",data.uid);
    }else if(data.equtype == 2){
        //电表
        memset(sql,0,sizeof(sql));
        sprintf(sql,"update userinfo set elecid = 0 where id = %d",data.uid);
    }
    int ret1 = mysql_query(mp,sql);
    if(ret1 != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }

    char res1[50] = "unbind success";
    ret = sendto(sockfd,res1,strlen(res1),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
    if(ret == -1){
        perror("sendto");
        exit(-1);
    }

    freeuserlist(uhead);
    initUserInfoList();
}
//充值
void _recharge(struct info infor){
    char sql[150]  = {0};

    struct top_up data;//解析用户发过来的包
    struct waterorelec_fee data1;//服务器发给设备端的组包
    struct addrlist *atemp = ahead;
    int ret = 0;
    int wid = 0;
    int eleid = 0;
    char tempname[20] = {0};
    char temptype[20] = {0};
    struct userlist *utemp = uhead->next;
    cJSON *json = NULL;
	json = cJSON_Parse(infor.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"equtype");
	if(node == NULL){
		printf("can't find equtype\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.equtype = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"id");
	if(node == NULL){
		printf("can't find id\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.id = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"money");
	if(node == NULL){
		printf("can't find money\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.money = node->valueint;
    }
    memset(tempname,0,sizeof(char)*20);
    while(utemp != NULL){
        if(utemp->data.id == data.id){
            data1.equtype = data.equtype;
            data1.fee = data.money;
            wid = utemp->data.waterid;
            eleid = utemp->data.elecid;
            strcpy(tempname,utemp->data.name);
            break;
        }
        utemp = utemp->next;
    }

    while(atemp != NULL){
        if(wid == atemp->data.waterid && eleid == atemp->data.elecid){
            ret = sendto(sockfd,&data1,sizeof(struct waterorelec_fee),0,(struct sockaddr *)&atemp->data.equaddr,sizeof(struct sockaddr));
            if(ret == -1){
                perror("sendto");
                exit(-1);
            }
        }
        atemp = atemp->next;
    }
    memset(temptype,0,sizeof(char)*20);
    if(data.equtype == 1){
        strcpy(temptype,"water");
    }else if(data.equtype == 2){
        strcpy(temptype,"elec");
    }
    memset(sql,0,sizeof(sql));
    sprintf(sql,"insert into rechrecord values(%d,'%s','%s',%d,now())",data.id,tempname,temptype,data.money);
    int ret1 = mysql_query(mp,sql);
    if(ret1 != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }
}

//接收设备端采集到的数据并处理
void recvfromEqu(struct info infor){
    int ret = 0;
    struct addrlist *atemp = ahead;
    struct userlist *utemp = uhead->next;
    struct addrlist *anode = NULL;
    struct equipment data;
    cJSON *json = NULL;
	json = cJSON_Parse(infor.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"waterid");
	if(node == NULL){
		printf("can't find waterid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.waterid = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"elecid");
	if(node == NULL){
		printf("can't find elecid\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.elecid = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"waterbalance");
	if(node == NULL){
		printf("can't find waterbalance\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.waterbalance = node->valueint;
    }
    node = cJSON_GetObjectItem(json,"elecbalance");
	if(node == NULL){
		printf("can't find elecbalance\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.elecbalance = node->valueint;
    }

    while(utemp != NULL){
        if(utemp->data.waterid == data.waterid){
            utemp->data.waterbalance == data.waterbalance;
        }
        if(utemp->data.elecid == data.elecid){
            utemp->data.elecbalance == data.elecbalance;
        }
    }
    while(atemp->next != NULL){
        if(atemp->data.waterid == data.waterid && atemp->data.elecid == data.elecid){
            break;
        }
        atemp = atemp->next;
    }
    if(atemp->next == NULL){
        anode = malloc(sizeof(struct addrlist));
        memset(anode,0,sizeof(struct addrlist));

        anode->data.equaddr = infor.addr;
        anode->data.waterid = data.waterid;
        anode->data.elecid = data.elecid;
        atemp->next = anode;
        anode->next = NULL;
        atemp = atemp->next;
    }
}

//查看个人信息
void getuserinfo(struct task msge){
    struct userlist *temp = uhead->next;
    struct userInfo data;
    int ret = 0;
    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"id");
	if(node == NULL){
		printf("can't find id\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		data.id = node->valueint;
    }
    cJSON_Delete(json);
    while(temp != NULL){
        if(temp->data.id == data.id){
            data = temp->data;
            break;
        }
    }
    cJSON *json1 = NULL;
	json1 = cJSON_CreateObject();
    cJSON_AddItemToObject(json1,"id",cJSON_CreateNumber(data.id));
	cJSON_AddItemToObject(json1,"name",cJSON_CreateString(data.name));
    cJSON_AddItemToObject(json1,"passwd",cJSON_CreateString(data.passwd));
    cJSON_AddItemToObject(json1,"waterid",cJSON_CreateNumber(data.waterid));
    cJSON_AddItemToObject(json1,"elecid",cJSON_CreateNumber(data.elecid));
    cJSON_AddItemToObject(json1,"waterbalance",cJSON_CreateNumber(data.waterbalance));
    cJSON_AddItemToObject(json1,"elecbalance",cJSON_CreateNumber(data.elecbalance));
    cJSON_AddItemToObject(json1,"phoneNumber",cJSON_CreateString(data.phoneNumber));
	char *s = cJSON_Print(json1);

    ret = sendto(sockfd,&data,sizeof(struct userInfo),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
    if(ret == -1){
        perror("sendto");
        exit(-1);
    }
    free(s);
    cJSON_Delete(json1);
}
//查看充值记录
void getRechRecord(struct task msge){
    int userid = 0;
    cJSON *json = NULL;
	json = cJSON_Parse(msge.buf);
	cJSON *node = NULL;
    node = cJSON_GetObjectItem(json,"id");
	if(node == NULL){
		printf("can't find id\n");
		exit(-1);
	}
    if(node->type == cJSON_Number){
		userid = node->valueint;
    }
    cJSON_Delete(json);
    char sql[150] = {0};
    sprintf(sql,"select * from rechrecord where id = %d",userid);
    int ret1 = mysql_query(mp,sql);
    if(ret1 != 0){
        printf("%s\n",mysql_error(mp));
        mysql_close(mp);
        exit(-1);
    }

    MYSQL_RES *res1 = NULL;
    MYSQL_ROW row;

    res1 = mysql_store_result(mp);
    row = mysql_fetch_row(res1);

    while(row != NULL){
        cJSON *json1 = NULL;
        json1 = cJSON_CreateObject();
        cJSON_AddItemToObject(json1,"id",cJSON_CreateNumber(atoi(row[0])));
        cJSON_AddItemToObject(json1,"name",cJSON_CreateString(row[1]));
        cJSON_AddItemToObject(json1,"rechType",cJSON_CreateString(row[2]));
        cJSON_AddItemToObject(json1,"fee",cJSON_CreateNumber(atoi(row[3])));
        cJSON_AddItemToObject(json1,"rechTime",cJSON_CreateString(row[4]));
        char *s = cJSON_Print(json1);

        int ret = sendto(sockfd,s,strlen(s),0,(struct sockaddr *)&msge.addr,sizeof(struct sockaddr));
        if(ret == -1){
            perror("sendto");
            exit(-1);
        }
        free(s);
        cJSON_Delete(json1);
        row = mysql_fetch_row(res1);
    }
    mysql_free_result(res1);
}
//查看远程控制记录
void getOperrecord(struct task msge){

}


//释放用户链表
void freeuserlist(struct userlist *uhead){
    struct userlist *temp = uhead->next;
    while(uhead != NULL){
        free(uhead);
        uhead = NULL;
        uhead = temp;
    }
    temp = NULL;
}
//释放管理员信息链表
void freemanlist(struct managerlist *mhead){
    struct managerlist *temp = mhead->next;
    while(mhead != NULL){
        free(mhead);
        mhead = NULL;
        mhead = temp;
    }
    temp = NULL;
}
